// 假设 Col 类型已定义
import { Col } from "./Col";
import { Config } from "./Config";
import { TimeoutManager } from "./TimeoutManager";
import { Tooler } from "./tooler";

const otherNum = 30; // 补充个数

export class Core {
    cols: Col[] = [];
    connData: any = {};
    ostIndex: number = 0;
    connCards: any[] = [];
    smlt: number[] = [1, 2, 3, 5];
    running: boolean = false;

    async play(): Promise<any[]> {
        this.ostIndex = 0;
        this.running = true;
        Config.bus.emit("ost", this.ostIndex)
        console.log("----开始");
        const conn = await Tooler.loadData(Config.DATA_URL);
        if (conn.code === 400) {
            alert(conn.msg);
            return [];
        }
        this.connData = conn.data;

        const ost = this.connData.dt.ost.slice(0, 1);
        const aimList: any[][] = Array(5).fill([]);

        ost.forEach((item:any[], idxBatch:number) => {
            const pack = item.map((type, i) => {
                return { type, idxBatch, idxNo: Math.floor(i / Config.CARDS_PER_COL) };
            });
            const ary = Tooler.groupArrayBySeven(pack);
            ary.forEach((temp, i) => {
                aimList[i] = temp.concat(aimList[i]);
            });
        });

        this.connData.dt.fill.forEach((items:any[], idxBatch:number) => {
            items.forEach((item, i) => {
                const pack = item.map((type:any) => {
                    return { type, idxBatch: idxBatch + 1, idxNo: i };
                });
                aimList[i] = pack.concat(aimList[i]);
            });
        });

        aimList.forEach((item, i) => {
            for (let i = 0; i < otherNum; i++) {
                item.push({
                    type: Tooler.getRandomInt(0, 10),
                    idxBatch: 0,
                    idxNo: i
                });
            }
        });

        console.log("aimList", aimList);
        return aimList;
    }

    setCols(cols: Col[]): void {
        this.cols = cols;
        this.cols.forEach((col, i) => col.initPosition(otherNum + Config.CARDS_PER_COL, i));
    }

    async dropDown(isScroll: boolean): Promise<void> {
        console.log("开始下落");

        this.cols.forEach(col => col.play());

        if (isScroll) {
            await Tooler.sleep(Config.SCROLL_TIMER + Config.GAP_TIMER * this.cols.length);
        } else {
            await Tooler.sleep(Config.DROP_DOWN_TIMER + 300);
        }
        console.log("下落动画结束");

        this.cols.forEach(col => col.updateOrder());
        console.log("更新索引");

        await Tooler.sleep(100);

        this.connCards = this.getWillRemoveItems();

        if (this.connCards.length === 0) {
            this.cols.forEach(col => col.removeOutside());
            this.ostIndex = 0;
            Config.bus.emit("ost", this.ostIndex)
            return;
        }
        Config.sounds.playBom()

        this.connCards.forEach((card, i) => {
          card.choose(true);
          TimeoutManager.setTimeout(() => {
            Config.bus.emit("start", card.mesh.position)
          }, 300 + i * 100);
          
        });
        console.log("选中连接牌");

        await Tooler.sleep(Config.CHOOSE_TIMER + 900);

        this.cols.forEach(col => {
            col.fixPosition(this.connCards);
            col.removeBottom();
            col.removeConn(this.connCards);
        });

        this.ostIndex++;
        Config.bus.emit("ost", this.ostIndex)

        await this.dropDown(false);
    }

    getWillRemoveItems(): any[] {
        const ary: any[] = [];
        const temp = this.connData.dt.cn.conn[this.ostIndex];
        let ids: number[] = [];

        for (const key in temp) {
            ids = ids.concat(temp[key]);
        }

        console.log("remove ids ", ids);

        this.cols.forEach(col => {
            col.cubes.forEach(cube => {
                if (ids.includes(cube.order)) {
                    ary.push(cube);
                }
            });
        });

        return ary;
    }

    async loadData(): Promise<any> {
        const token = 'your_token_here';
        return new Promise((resolve) => {
            fetch(Config.DATA_URL, {
                headers: {
                    'Authorization': `Bearer ${token}`
                }
            })
                .then(response => response.json())
                .then(data => {
                    resolve(data);
                })
                .catch(error => {
                    resolve(null);
                });
        });
    }
}